module nazo.ber;
/**
 * BER圧縮整数の変換API
 * History:
 *          0.0.0.1 バージョン付け開始
 * Authors: Nazo
 * Version: 0.0.0.1
 * License: Public Domain
*/
import std.string, std.stdio, nazo.array;
///ber圧縮整数からUintに変換します。
uint toUint(ubyte[] data){
  uint len;
  return toUint(data,len);
}
///ber圧縮整数からUintに変換します。
///第二引数は元の圧縮整数の長さを返します(dataの途中で圧縮整数が終わる場合があるので)。
uint toUint(ubyte[] data,out uint len){
  uint re=0;
  foreach(ubyte i;data){
    len++;
    if(i<128){
      re=re*128+cast(uint)i;
      debug(ber){
        writef("%d\n",data);
      }
      return re;
    }else{
      re=re*128+i-128;
    }
  }
  throw new BerException("Bad size");
}

///数字からber圧縮整数へ変換します。
ubyte[] toBer(uint from){
  ubyte[] re;
  int len;
  while(true){
    uint i=from%128;

    if(len==0)
      re~=i;
    else
      re~=i+128;

    if(from/128==0)
      break;
    from=from/128;
    len++;
  }
  return re.reverse;
}

class BerException : Exception{
  this(string name){
    super("Ber Exception: "~name);
  }
}

unittest{
  assert(.toUint([0x64])==100);
  assert(.toUint([0x86,0x8D,0x1F])==99999);
  assert(.toBer(99999)==[cast(ubyte)0x86,0x8D,0x1F]);
}
